#include "geneticAlgorithm.h"

GA::GA(int popSize) {
    // reserve space
    comp(popSize);
    population(popSize);
    prevPopulation(popSize);

    // randomly populate current population
    RNG rng(time(null));
    int i;
    for (i=0; i < popSize; i++) {
        rng.fill(population.at(i), RNG::UNIFORM, 0, 1);
        threshold(population.at(i), population.at(i), 0.5, 1, THRESH_BINARY);
    }

    updateComplexities(); // update complexities of current population
    sort(); // sort population by complexity

    advance();
}

void GA::updateComplexities() {
    int i;
    for (i=0; i < population.size; i++)
        comp.at(i) = complexity(population.at(i));
}

double GA::complexity(Mat cur) {
    Mat outline;
    int ink = countNonZero(cur); // get number of 1 pixels
    dilate(cur, outline, Mat());
    outline = outline - cur; // get outline of character
    dilate(outline, outline, Mat());
    int perimeter = countNonZero(outline) / 3;

    return ((float)perimeter * perimeter / ink);
}

void GA::sortComplexities() {
    sort(population.begin(), population.end(), complexCompare);
}

void GA::complexCompare(Mat a, Mat b) {
    return (complexity(a) > complexity(b))
}

void GA::advance() {
    prevPopulation.erase(prevPopulation.begin(), prevPopulation.end()); // destroy old generation
    int i;
    for (i=0; i < population.size; i++)
        prevPopulation.push_back(population.at(i).clone()); // make new generation old generation
    population.erase(population.begin(), population.end()); // blank slate
}
